﻿//// Copyright (c) Microsoft Corporation. All rights reserved

(function () {
    "use strict";

    var allJoyn = Windows.Devices.AllJoyn;
    var onboarding = org.alljoyn.Onboarding;

    var page = WinJS.UI.Pages.define("/html/scenario2.html", {
        ready: function (element, options) {
            scenarioInit();
        },
        unload: function (element, options) {
            scenarioCleanup();
        }
    });

    var isBusAttachmentConnected = false;
    var key, producer, busAttachment;

    function scenarioInit() {
        producerOptions.style.display = "none";
        launchButton.onclick = launchButtonClickHandler;

        var networkscanList = AppData.getSampleNetworkScanList();
        for (var i = 0; i < networkscanList.length; i++) {
            var option = document.createElement("option");
            option.text = networkscanList[i].value1;
            sampleNetworkSelect.add(option);
        }
        sampleNetworkSelect.onchange = sampleNetworkSelectChangeHandler;
        sampleNetworkSelectChangeHandler();
    }

    function scenarioCleanup() {
        if (producer != null) {
            producer.service.onconfigurewificalled = null;
            producer.service.onconnectcalled = null;
            producer.service.onoffboardcalled = null;
            producer.service.ongetscaninfocalled = null;
            producer.service.ongetversionrequested = null;
            producer.service.ongetstaterequested = null;
            producer.service.ongetlasterrorrequested = null;
            producer.stop();
        }
        if (busAttachment != null) {
            busAttachment.onstatechanged = null;
            busAttachment.onauthenticationcomplete = null;
            busAttachment.oncredentialsrequested = null;
            busAttachment.disconnect();
            isBusAttachmentConnected = false;
        }
    }

    function launchButtonClickHandler() {
        if (isBusAttachmentConnected) {
            reportStatus("Already launched.");
        } else {
            reportStatus("Launching...");

            busAttachment = new allJoyn.AllJoynBusAttachment();
            busAttachment.onstatechanged = stateChangedHandler;
            busAttachment.authenticationMechanisms.clear();
            busAttachment.authenticationMechanisms.append(allJoyn.AllJoynAuthenticationMechanism.ecdheSpeke);
            busAttachment.onauthenticationcomplete = authenticationCompleteHandler;
            busAttachment.oncredentialsrequested = credentialsRequestedHandler;

            // Generate the one-time 6-digit numeric pre-shared key.
            key = Math.floor((Math.random() * 1000000) + 1);
            keyDisplay.textContent = key;

            // Initialize the producer object generated by the AllJoynCodeGenerator tool.
            producer = new onboarding.OnboardingProducer(busAttachment);

            // Instantiate OnboardingService which will handle the onboarding method calls.
            producer.service = new onboarding.OnboardingServiceEventAdapter();
            producer.service.onconfigurewificalled = configureWiFiCalledHandler;
            producer.service.onconnectcalled = connectCalledHandler;
            producer.service.onoffboardcalled = offboardCalledHandler;
            producer.service.ongetscaninfocalled = getScanInfoCalledHandler;
            producer.service.ongetversionrequested = getVersionRequestedHandler;
            producer.service.ongetstaterequested = getStateRequestedHandler;
            producer.service.ongetlasterrorrequested = getLastErrorRequestedHandler;

            // Start advertising the service.
            producer.start();
        }
    }

    function sampleNetworkSelectChangeHandler() {
        var networkscanList = AppData.getSampleNetworkScanList();

        if (networkscanList[sampleNetworkSelect.selectedIndex].value2 === OnboardingEnumTypes.AuthenticationType.Open) {
            passwordDisplay.textContent = "";
        } else {
            passwordDisplay.textContent = AppData.sampleNetworkPassword;
        }

        authTypeDisplay.textContent = OnboardingEnumTypes.AuthenticationType.properties[networkscanList[sampleNetworkSelect.selectedIndex].value2 + OnboardingEnumTypes.authenticationIndexOffset].name;
    }

    function stateChangedHandler(args) {
        switch (args.detail[0].state) {
            case allJoyn.AllJoynBusAttachmentState.disconnected:
                reportStatus("Disconnected from the AllJoyn bus attachment with AllJoyn status: 0x" + args.detail[0].status.toString(16));
                isBusAttachmentConnected = false;
                producerOptions.style.display = "none";
                break;
            case allJoyn.AllJoynBusAttachmentState.connected:
                reportStatus("Launched.");
                isBusAttachmentConnected = true;
                producerOptions.style.display = "block";
                break;
        }
    }

    function authenticationCompleteHandler(args) {
        if (args.detail[0].succeeded) {
            reportStatus("Authentication was successful.");
        } else {
            reportError("Authentication failed.");
        }
    }

    function credentialsRequestedHandler(args) {
        if (args.detail[0].credentials.authenticationMechanism == allJoyn.AllJoynAuthenticationMechanism.ecdheSpeke) {
            args.detail[0].credentials.passwordCredential.password = key;
        } else {
            reportError("Unexpected authentication mechanism.");
        }
    }

    function configureWiFiCalledHandler(args) {
        reportStatus("Configure WiFi request received.");
        AppData.onboardingConfiguration.ssid = args.detail[0].ssid;
        AppData.onboardingConfiguration.passphrase = args.detail[0].passphrase;
        AppData.onboardingConfiguration.authenticationType = args.detail[0].authType;
        AppData.onboardingProperties.configurationState = OnboardingEnumTypes.ConfigurationState.NotValidated;
        args.detail[0].result = onboarding.OnboardingConfigureWiFiResult.createSuccessResult(OnboardingEnumTypes.ConfigureWiFiResultStatus.Concurrent);
    }

    function connectCalledHandler(args) {
        reportStatus("Connect Request received. Attempting to connect...");
        AppData.onboardingProperties.configurationState = OnboardingEnumTypes.ConfigurationState.Validating;

        // 5 second delay to simulate connection attempt time.
        setTimeout(function () {
            var returnArg = new onboarding.Onboarding();

            var ssid = AppData.onboardingConfiguration.ssid;
            if ((typeof ssid === 'undefined') || (ssid == null) || (!/\S/.test(ssid))) {
                returnArg.value1 = OnboardingEnumTypes.ConnectionResultCode.ErrorMessage;
                returnArg.value2 = "Invalid SSID";
                AppData.onboardingProperties.configurationState = OnboardingEnumTypes.ConfigurationState.Error;
            } else {
                var foundSsid = false;
                var supportedProtocol = false;

                var networkscanList = AppData.getSampleNetworkScanList();
                for (var i = 0; i < networkscanList.length; i++) {
                    if (networkscanList[i].value1 === ssid) {
                        foundSsid = true;
                        if (AppData.onboardingConfiguration.authenticationType === OnboardingEnumTypes.AuthenticationType.Any) {
                            supportedProtocol = true;
                        } else if (AppData.onboardingConfiguration.authenticationType === OnboardingEnumTypes.AuthenticationType.WpaAuto) {
                            if ((networkscanList[i].value2 === OnboardingEnumTypes.AuthenticationType.WpaTkip) || (networkscanList[i].value2 === OnboardingEnumTypes.AuthenticationType.WpaCcmp)) {
                                supportedProtocol = true;
                            }
                        } else if (AppData.onboardingConfiguration.authenticationType === OnboardingEnumTypes.AuthenticationType.Wpa2Auto) {
                            if ((networkscanList[i].value2 === OnboardingEnumTypes.AuthenticationType.Wpa2Tkip) || (networkscanList[i].value2 === OnboardingEnumTypes.AuthenticationType.Wpa2Ccmp)) {
                                supportedProtocol = true;
                            }
                        } else {
                            if (networkscanList[i].value2 === AppData.onboardingConfiguration.authenticationType) {
                                supportedProtocol = true;
                            }
                        }
                        break;
                    }
                }

                if (foundSsid) {
                    if (supportedProtocol) {
                        if (AppData.onboardingConfiguration.authenticationType === OnboardingEnumTypes.AuthenticationType.Open) {
                            returnArg.value1 = OnboardingEnumTypes.ConnectionResultCode.Validated;
                            returnArg.value2 = "Connected successfully";
                            AppData.onboardingProperties.configurationState = OnboardingEnumTypes.ConfigurationState.Validated;
                        } else {
                            if (AppData.onboardingConfiguration.passphrase.toLowerCase() === convertUtf8ToHex(AppData.sampleNetworkPassword)) {
                                returnArg.value1 = OnboardingEnumTypes.ConnectionResultCode.Validated;
                                returnArg.value2 = "Connected successfully";
                                AppData.onboardingProperties.configurationState = OnboardingEnumTypes.ConfigurationState.Validated;
                            } else {
                                returnArg.value1 = OnboardingEnumTypes.ConnectionResultCode.Unauthorized;
                                returnArg.value2 = "Invalid password";
                                AppData.onboardingProperties.configurationState = OnboardingEnumTypes.ConfigurationState.Error;
                            }
                        }
                    } else {
                        returnArg.value1 = OnboardingEnumTypes.ConnectionResultCode.UnsupportedProtocol;
                        returnArg.value2 = "Unsupported authentication mechanism";
                        AppData.onboardingProperties.configurationState = OnboardingEnumTypes.ConfigurationState.Error;
                    }
                } else {
                    returnArg.value1 = OnboardingEnumTypes.ConnectionResultCode.Unreachable;
                    returnArg.value2 = "Configured SSID unreachable";
                    AppData.onboardingProperties.configurationState = OnboardingEnumTypes.ConfigurationState.Error;
                }
            }

            producer.signals.connectionResult(returnArg);
            AppData.onboardingProperties.lastErrorCode = returnArg.value1;
            AppData.onboardingProperties.lastErrorMessage = returnArg.value2;

            if (returnArg.value1 === OnboardingEnumTypes.ConnectionResultCode.Validated) {
                reportStatus("Onboarding successful. Connected to " + ssid);
            } else {
                reportError("Onboarding Failed. Attempt to connect failed with result code: " + OnboardingEnumTypes.ConnectionResultCode.properties[returnArg.value1].name + " and message: " + returnArg.value2 + ".");
            }
        }, 5000);

        args.detail[0].result = onboarding.OnboardingConnectResult.createSuccessResult();
    }

    function offboardCalledHandler(args) {
        AppData.onboardingConfiguration.ssid = null;
        AppData.onboardingConfiguration.passphrase = null;
        AppData.onboardingConfiguration.authenticationType = OnboardingEnumTypes.AuthenticationType.Any;
        AppData.onboardingProperties.configurationState = OnboardingEnumTypes.ConfigurationState.NotConfigured;
        args.detail[0].result = onboarding.OnboardingOffboardResult.createSuccessResult();
    }

    function getScanInfoCalledHandler(args) {
        args.detail[0].result = onboarding.OnboardingGetScanInfoResult.createSuccessResult(1, AppData.getSampleNetworkScanList());
    }

    function getVersionRequestedHandler(args) {
        args.detail[0].result = onboarding.OnboardingGetVersionResult.createSuccessResult(1);
    }

    function getStateRequestedHandler(args) {
        args.detail[0].result = onboarding.OnboardingGetStateResult.createSuccessResult(AppData.onboardingProperties.configurationState);
    }

    function getLastErrorRequestedHandler(args) {
        var lastError = new onboarding.OnboardingLastError();
        lastError.value1 = AppData.onboardingProperties.lastErrorCode;
        lastError.value2 = AppData.onboardingProperties.lastErrorMessage;
        args.detail[0].result = onboarding.OnboardingGetLastErrorResult.createSuccessResult(lastError);
    }

    function convertUtf8ToHex(str) {
        var tempBuffer = Windows.Security.Cryptography.CryptographicBuffer.convertStringToBinary(str, Windows.Security.Cryptography.BinaryStringEncoding.Utf8);
        return Windows.Security.Cryptography.CryptographicBuffer.encodeToHexString(tempBuffer);
    }

    function reportStatus(message) {
        WinJS.log && WinJS.log(message, "sample", "status");
    }

    function reportError(message) {
        WinJS.log && WinJS.log(message, "sample", "error");
    }
})();
